using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace Catchbase.TestTools
{
    public static class Assertions
    {
        public static void MustBeTrue(this bool value, string message = "", params object[] parameters)
        {
            Assert.IsTrue(value, string.Format(message, parameters));
        }

        public static void MustBeFalse(this bool value, string message = "", params object[] parameters)
        {
            Assert.IsFalse(value, string.Format(message, parameters));
        }

        public static void MustBeNotNullOrEmpty(this string value)
        {
            Assert.IsFalse(string.IsNullOrEmpty(value));
        }

        public static void MustBeEmpty(this string value)
        {
            Assert.IsTrue(string.IsNullOrEmpty(value));
        }

        public static void MustBeInstanceOf<T>(this T obj, Type type)
        {
            Assert.IsInstanceOfType(obj, type);
        }

        public static void MustBeInstanceOf<TTYPE>(this object obj)
        {
            Assert.IsInstanceOfType(obj, typeof(TTYPE));
        }

        public static void MustEqual<T>(this T obj, T expected)
        {
            Assert.AreEqual(expected, obj);
        }

        public static void MustBeSame<T>(this T obj, T expected)
        {
            Assert.AreSame(expected, obj);
        }

		public static void MustBeEqual<T>(this T obj, T expected)
		{
			Assert.AreEqual(expected, obj);
		}

        public static void MustNotBeSame<T>(this T obj, T expected)
        {
            Assert.AreNotSame(expected, obj);
        }

		public static void MustBeGreaterThan(this int obj, int expected)
		{
			Assert.IsTrue(obj > expected);
		}

		public static void MustNotBeNull<T>(this T obj)
		{
			Assert.IsNotNull(obj);
		}

		public static void MustBeNull<T>(this T obj)
		{
			Assert.IsNull(obj);
		}

        public static void MustContain<T>(this IEnumerable<T> obj, params T[] expected)
        {
            var items = obj.ToList();
            foreach (var exp in expected)
                Assert.IsTrue(items.Contains(exp));
        }

        public static void MustNotContain<T>(this IEnumerable<T> obj, params T[] expected)
        {
            var items = obj.ToList();
            foreach (var exp in expected)
                Assert.IsFalse(items.Contains(exp), string.Format("IEnumerable contains unexpected object of {0}", typeof(T).Name));
        }

        public static void MustContainExactObjects<T>(this IEnumerable<T> obj, params T[] expected)
        {
            var items = obj.ToList();
            items.MustContain(expected);
            items.MustSize(expected.Length);
        }

        public static void MustSize<T>(this IEnumerable<T> obj, int size)
        {
            Assert.AreEqual(size, obj.Count());
        }

        public static void MustStartWith(this string text, string expected)
        {
            Assert.IsTrue(text.StartsWith(expected));
        }
    }
}